package com.example.service.impl.image;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.dto.Account;
import com.example.entity.dto.StoreImage;
import com.example.mapper.AccountMapper;
import com.example.mapper.ImageStoreMapper;
import com.example.service.ImageService;
import com.example.utils.Const;
import com.example.utils.FlowUtils;
import io.minio.*;
import io.minio.errors.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.IOUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Component
@ConditionalOnExpression(value = "#{'minio'.equals(environment.getProperty('spring.image.oss.type'))}")
public class ImageServiceImpl extends ServiceImpl<ImageStoreMapper, StoreImage> implements ImageService {


    @Resource
    MinioClient minioClient;

    @Resource
    AccountMapper accountMapper;

    @Resource
    FlowUtils flowUtils;

    private SimpleDateFormat format =  new SimpleDateFormat("yyyyMMdd");


    //上传头像并返回地址
    @Override
    public String uploadAvatar(MultipartFile file, int id) throws Exception {
        String imageName = UUID.randomUUID().toString().replace("-", "");
        imageName = "/avatar/" + imageName;
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket("school-forum")
                .stream(file.getInputStream(), file.getSize(), -1)
                .object(imageName)
                .build();
        try {
            minioClient.putObject(args);
            String avatar = accountMapper.selectById(id).getAvatar();
            this.deleteOldAvatar(avatar);

            if (accountMapper.update(null, Wrappers.<Account>update().eq("id", id).set("avatar", imageName)) == 0) {
                return null;
            } else {
                log.info("用户上传了头像" + file.getOriginalFilename());
                return imageName;
            }

        } catch (Exception e) {
            log.error("上传头像失败" + e.getMessage(), e);
            return null;
        }
    }

    //获取一个图像文件，并将其内容写入到提供的 OutputStream 中
    @Override
    public void fetchImageFromMinio(OutputStream stream, String image) throws Exception {
        GetObjectArgs args = GetObjectArgs.builder()
                .bucket("school-forum")
                .object(image)
                .build();
        GetObjectResponse response = minioClient.getObject(args);
        IOUtils.copy(response, stream);
    }

    //上传帖子的图片
    @Override
    public String uploadImage(MultipartFile file, int id) throws Exception {
        String key = Const.FORUM_IMAGE_COUNTER + id;
//        if (flowUtils.limitPeriodCounterCheck(key, 20, 3600)) {
//            return null;
//        }
        String imageName = UUID.randomUUID().toString().replace("-", "");
        Date date = new Date();
        imageName = "/cache/" + format.format(date) + "/" + imageName + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        System.out.println(imageName);
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket("school-forum")
                .stream(file.getInputStream(), file.getSize(), -1)
                .object(imageName)
                .build();
        try {
            minioClient.putObject(args);
            if (this.save(new StoreImage(id, imageName, date))) {
                return imageName;
            } else {
                log.info("上传成功图片失败");
                return null;
            }
        } catch (Exception e) {
            log.info("上传图片失败");
            return null;
        }
    }

    private void deleteOldAvatar(String avatar) throws Exception {
        if (avatar == null || avatar.isEmpty()) {
            return;
        }
        RemoveObjectArgs remove = RemoveObjectArgs.builder()
                .bucket("study")
                .object(avatar)
                .build();
        minioClient.removeObject(remove);
        log.info("删除了旧头像:" + avatar);
    }
}
